<template>
  <el-dialog
    ref="dialog"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :title="props.title"
    width="950px"
    @closed="handleDialogClosed"
    @open="handleDialogOpen"
  >
    <el-row>
      <el-col
        :span="6"
        class="border-right-default"
      >
        <el-input
          v-model="filterText"
          placeholder="请输入分类名称"
          class="search-input"
        >
          <!-- <template
            #append
          >
            <el-button
              class="search-btn"
            >
              <i class="el-icon-search" />
            </el-button>
          </template> -->
        </el-input>

        <el-tree
          ref="treeRef"
          class="filter-tree"
          node-key="id"
          :data="fileCategories"
          :props="defaultProps"
          default-expand-all
          :filter-node-method="filterNode"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span
                :class="{'active': data.id === listParams.pid}"
                @click="handleCategoryPidChange(data.id)"
              >{{ node.label }}</span>
            </span>
            <div class="more-menu">
              <el-dropdown class="fl-right">
                <span class="el-dropdown-link">
                  <el-icon class="el-icon-more" />
                </span>
                <template #dropdown>
                  <el-dropdown-menu :disabled="isCateDeleting || isCateUpdating">
                    <el-dropdown-item @click="addCate(data.id)">
                      添加分类
                    </el-dropdown-item>
                    <template v-if="data.id !== 0">
                      <el-dropdown-item @click="editCate(data.id)">
                        编辑分类
                      </el-dropdown-item>
                      <el-dropdown-item @click="removeCate(data.id)">
                        删除分类
                      </el-dropdown-item>
                    </template>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-tree>
      </el-col>
      <el-col
        :span="18"
      >
        <app-card>
          <template #header>
            <el-button
              :type="multipleSelection.length ? 'primary' : 'default'"
              :disabled="multipleSelection.length < 1"
              @click="emit('confirm', multipleSelection)"
            >
              使用选中图片
            </el-button>
            <el-upload
              action="xxx"
              multiple
              :limit="3"
              :http-request="handleUpload"
              :show-file-list="false"
            >
              <el-button
                type="primary"
              >
                上传图片
              </el-button>
            </el-upload>
            <el-button
              type="danger"
              :disabled="multipleSelection.length < 1 || isDeleting"
              @click="removeSelected"
            >
              删除图片
            </el-button>
            <!-- todo: 抽取组件支持级联选择器 -->
            <!-- <el-input>
              <el-tree
                ref="treeRef"
                class="filter-tree"
                node-key="id"
                :data="fileCategories"
                :props="defaultProps"
                default-expand-all
                :filter-node-method="filterNode"
              >
                <template #default="{ node, data }">
                  <span class="custom-tree-node">
                    <span
                      :class="{'active': data.id === listParams.pid}"
                      @click="handleCategoryPidChange(data.id)"
                    >{{ node.label }}</span>
                  </span>
                </template>
              </el-tree>
            </el-input> -->
            <el-select
              placeholder="图片移动至"
              v-model="moveCate"
              @change="moveSelectedToCate"
              :disabled="multipleSelection.length < 1 || isMoving"
            >
              <el-option
                v-for="item in fileCategories"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </template>
          <div
            class="pictrue-list acea-row"
            :disabled="listLoading"
          >
            <el-row
              :gutter="5"
            >
              <el-col
                v-if="listLoading"
                :span="24"
                class="images-no"
              >
                <el-icon
                  class="el-icon-loading"
                  style="font-size: 60px; color: rgb(219, 219, 219);"
                />
              </el-col>

              <el-col
                v-else-if="!listLoading && !list.length"
                :span="24"
                class="images-no"
              >
                <i
                  class="el-icon-picture"
                  style="font-size: 60px; color: rgb(219, 219, 219);"
                /><span
                  class="images-no-sp"
                >图片库为空</span>
              </el-col>
              <el-col
                v-else
                v-for="row in list"
                :key="row.att_id"
                :span="4"
              >
                <div
                  class="pictrue-list-pic"
                >
                  <el-row
                    @click="handleSelectionChange(row)"
                  >
                    <el-image
                      :src="row.att_dir"
                      fit="contain"
                      :class="{'on': findFileItemIndex(row)+1}"
                    >
                      <template #error>
                        <div class="image-slot">
                          <i
                            class="el-icon-picture"
                            style="font-size: 60px; color: rgb(219, 219, 219);"
                          />
                        </div>
                      </template>
                    </el-image>
                    <el-badge
                      class="number"
                      type="danger"
                      size="large"
                      v-if="findFileItemIndex(row)+1"
                      :value="findFileItemIndex(row)+1"
                    />
                  </el-row>

                  <div
                    class="pic-item-title"
                  >
                    <p
                      style="width: 80%;"
                    >
                      {{ row.real_name.length > 8 ? `${row.real_name.slice(0,2)}...${row.real_name.slice(row.real_name.length-6)}` : row.real_name }}
                    </p>
                  </div><div
                    class="nameStyle"
                    style="display: none;"
                  >
                    {{ row.real_name }}
                  </div>
                </div>
              </el-col>
            </el-row>
          </div>
          <app-pagination
            v-model:page="listParams.page"
            v-model:limit="listParams.limit"
            :list-count="listCount"
            :load-list="loadList"
            :disabled="listLoading"
          />
        </app-card>
      </el-col>
    </el-row>
    <app-file-category-form
      v-model="formVisible"
      v-model:cate-id="cateId"
      v-model:pid="pid"
      @success="handleFormSuccess"
    />
  </el-dialog>
</template>

<script lang="ts" setup>
import type { PropType } from 'vue'
import { ref, watch, reactive, onMounted, computed, watchEffect } from 'vue'
import { ElMessage, ElTree } from 'element-plus'
import { getFiles, getFileCategories, uploadFile, moveFiles, deleteFile } from '@/api/file'
import type { FileItem, FileCategory } from '@/api/types/file'

const props = defineProps({
  title: {
    type: String,
    default: '上传商品图'
  },
  maxSelect: {
    type: Number,
    default: 1
  },
  defaultSelected: {
    type: Array as PropType<string[]>,
    default: () => []
  }
})

const emit = defineEmits(['confirm'])
const fileCategories = ref<FileCategory[]>([])
const list = ref<FileItem[]>([]) // 列表数据
const listCount = ref(0)
const listLoading = ref(true)
const isDeleting = ref(false)
const isCateDeleting = ref(false)
const isCateUpdating = ref(false)
const isMoving = ref(false)
const formVisible = ref(false)
const cateId = ref<number|null>(null)
const pid = ref(0)
const listParams = reactive({ // 列表数据查询参数
  page: 1, // 当前页码
  limit: 18, // 每页大小
  pid: 0
})
const multipleSelection = ref<string[]>([])

const moveCate = ref('')
const multipleSelectionId = computed(() => {
  const tmpIds: number[] = []

  multipleSelection.value.forEach(selectItem => {
    const found = list.value.find(item => item.att_dir === selectItem)
    if (found) {
      tmpIds.push(found.att_id)
    }
  })
  return tmpIds
})
const removeCate = (id: number) => {
  isCateDeleting.value = true
}

watchEffect(() => {
  if (formVisible.value === false) {
    formVisible.value = false
    isCateUpdating.value = false
    isCateDeleting.value = false
    cateId.value = null
    pid.value = 0
  }
})

const addCate = (id: number) => {
  formVisible.value = true
  pid.value = id
  isCateUpdating.value = true
}

const editCate = (id: number) => {
  formVisible.value = true
  cateId.value = id
  isCateUpdating.value = true
}
const handleFormSuccess = () => {
  formVisible.value = false
  isCateUpdating.value = false
  isCateDeleting.value = false
  cateId.value = null
  loadFileCategories()
}

const moveSelectedToCate = async (pid: number) => {
  if (multipleSelectionId.value.length < 1) {
    ElMessage.warning('请选择图片')
  } else {
    isMoving.value = true
    await moveFiles({ pid, images: multipleSelectionId.value.join(',') })
    ElMessage.success('移动成功')
    isMoving.value = false
    // 重新加载渲染列表
    listParams.page = 1
    loadList()
  }
}
const handleDialogClosed = () => {
  // 重置以上数据
  // 貌似也没什么需要重置的
}
const handleDialogOpen = () => {
  Promise.all([loadList(), loadFileCategories()]).finally(() => {
    listLoading.value = false
  })
  multipleSelection.value = [...props.defaultSelected]
}
onMounted(() => {

})

const findFileItemIndex = (val: FileItem) => multipleSelection.value.findIndex(item => item === val.att_dir)

const handleSelectionChange = (val: FileItem) => {
  const hasSelectedIdx = findFileItemIndex(val)
  if (hasSelectedIdx > -1) {
    multipleSelection.value.splice(hasSelectedIdx, 1)
  } else if (multipleSelection.value.length < props.maxSelect) {
    multipleSelection.value.push(val.att_dir)
  } else if (multipleSelection.value.length === 1 && props.maxSelect === 1) {
    multipleSelection.value = [val.att_dir]
  }
}

const handleCategoryPidChange = (id: number) => {
  listParams.pid = id
  listParams.page = 1
  loadList()
}

const loadList = async () => {
  listLoading.value = true
  const data = await getFiles(listParams).finally(() => {
    listLoading.value = false
  })
  list.value = data.list
  listCount.value = data.count
}

const loadFileCategories = async () => {
  const data = await getFileCategories({ name: '' })
  fileCategories.value = [{
    id: 0,
    pid: 0,
    name: '全部图片',
    enname: '',
    title: '全部图片',
    children: []
  }, ...data.list]
}
// 切换分类时需要用到
// const handleQuery = async () => {
//   listParams.page = 1 // 查询默认从第1页开始
//   loadList()
// }
const removeSelected = async () => {
  if (multipleSelectionId.value.length < 1) {
    ElMessage.warning('请选择图片')
  } else {
    isDeleting.value = true
    await deleteFile(multipleSelectionId.value.join(','))

    multipleSelection.value = []
    ElMessage.success('删除成功')
    isDeleting.value = false
    // 重新加载渲染列表
    listParams.page = 1
    loadList()
  }
}
const handleUpload = async ({ file }: { file: File }) => {
  await uploadFile({
    pid: listParams.pid,
    file
  })
  loadList()
}

interface Tree {
  id: number
  pid: number
  name: string
  enname: string
  title: string
  children?: Tree[]
}

const filterNode = (value: string, data: Tree) => {
  if (!value) {
    return true
  }
  return data.name.includes(value)
}

// const data: Tree[] = []

const filterText = ref('')
const treeRef = ref<InstanceType<typeof ElTree>>()

const defaultProps = {
  children: 'children',
  label: 'name'
}

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

</script>

<style lang="scss" scoped>
:deep(.el-col.border-right-default) {
  border-right: 1px solid #eee;
}
:deep(.el-card) {
  box-shadow: none !important;
  border: none;
}
:deep(.el-dropdown) {
  margin-right: 8px;
  display: none;
  &.fl-right {
    float: right;
  }
}
:deep(.el-tree-node__content) {
  &:hover {
    .el-dropdown {
      display: block;
    }
  }
  .custom-tree-node .active {
    color: #409EFF;
  }
  .more-menu {
    flex: auto;
  }
}
:deep(.pictrue-list) {
  width: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  height: 300px;
  .pictrue-list-pic {
    position: relative;
    width: 100px;
    cursor: pointer;

    .el-image {
      width: 100%;
      border: 2px solid #fff;
      height: 100px;
      &.on {
        border: 2px solid #5fb878;
      }
      & .image-slot {
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
    .pic-item-title {
      display: flex;
      align-items: center;
      justify-content: space-between;
      p {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        height: 20px;
        text-align: center;
      }
    }
    .number {
      height: 33px;
      position: absolute;
      right: 5px;
      top: 5px;
    }
  }
}
.images-no {
  display: flex !important;
  justify-items: center;
  align-items: center;
  flex-direction: column;
  margin: 65px 0;
}
.images-no-sp {
  font-size: 13px;
  color: #dbdbdb;
  line-height: 3;
}
</style>
